package controllers;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.AutomaticObjective;
import models.Comible;
import models.ComidaDieta;
import models.Dieta;
import models.EstadoPaciente;
import models.Ingerido;
import models.Nutri;
import models.Paciente;
import models.PacienteAdquirido;
import models.Plan;
import models.TemplatePlan;
import notifiers.Notificador;
import play.db.Model;
import play.exceptions.TemplateNotFoundException;
import play.mvc.With;
import controllers.CRUD.ObjectType;
import controllers.deadbolt.Deadbolt;
import controllers.deadbolt.Restrict;
import controllers.securesocial.SecureSocial;

@With({SecureSocial.class, Deadbolt.class})
public class Pacientes extends CustomCRUD {
	
	public static void index() {
		
		Paciente paciente = (Paciente)getUsuarioLogueado();
		
		if (getControllerClass() == CRUD.class) {
			forbidden();
		}
		
		List<Plan> planes = Plan.findByMismoPacienteActiva(paciente.getId());
    	
		if (planes != null && planes.size() == 1) {
			// el usuario tiene un plan activo
			try {
				Plan plan = planes.get(0);
				List<Dieta> dietas = plan.getDietas();
				
				Long dietaId = null;
				
				//TODO: nico, modificado porque siempre recorria todas las dietas y se quedaba con el ultimo dietaId
//				for(Dieta dieta : dietas){
//					if(dieta.getPlan().id == plan.getId()){
//						dietaId = dieta.id;
//						break;
//					}
//				}
				
				
				// con dietaId=null el dietas.show devuelve la dieta del dia actual
				Dietas.show(planes.get(0).getId(), dietaId);
			} catch (Exception e) {
				// error intentar recuperar la dieta para registrar ingeridos, se muestra la pagina inicial
				e.printStackTrace();
			}
		}
		render();
    }
    
	@Restrict("NUTRI")
	public static void list(int page, String search, String searchFields, String orderBy, String order) {
		
		Nutri nutri = (Nutri)getUsuarioLogueado();
		
		Long userId = nutri.id;
		
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		
		if (page < 1) {
			page = 1;
		}
		
		List<Model> objects = type.findPage(page, search, searchFields, orderBy, order, (String) request.args.get("where"));
		
		List<Model> filteredObjects = new ArrayList<Model>();
		
		for (Model model : objects) {
			if (((Paciente)model).getNutricionista() != null
					&&((Paciente)model).getNutricionista().getId().equals(userId)
					&& ((Paciente)model).getEstadoPaciente() != null) {
				
				filteredObjects.add(model);
			}
		}
	    
		objects = filteredObjects;
		
		Long count = new Long(objects.size());
		Long totalCount = new Long(objects.size());
		
        try {
            render(type, objects, count, totalCount, page, orderBy, order, userId);
        } catch (TemplateNotFoundException e) {
            render(getControllerName() + "/list.html", type, objects, count, totalCount, page, orderBy, order, userId);
        }
    }
	
	/**
	 * Pregunta por la asignacion al nutricionista solicitado desde el link correspondiente 
	 */
	public static void confirmarPedido(Long nutriId) {
		
		Nutri nutri = Nutri.findById(nutriId);
		String nombre = nutri.getNombre();
		String email = nutri.getEmail();
		
		render(getControllerName() + "/confirmarPedido.html", nombre, email);
	}
	
	/**
	 * Realiza la confirmacion del nutricionista asignado 
	 */
	public static void confirmarNutri(Long nutriId) {
		
		Paciente paciente = (Paciente) getUsuarioLogueado();
		paciente.setEstadoPaciente(EstadoPaciente.CONFIRMADO);
		paciente.save();
		
		// TODO: arreglar cuando existe un paciente nuevo, no queda registrado la relacion con el nutri
		
		index();
	}
	
	// Le asigna un paciente a un template
	public static void asignarPacientes(String pacienteId) throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Paciente object = (Paciente)type.findById(pacienteId);
		
		List<TemplatePlan> templates = TemplatePlan.find("byAutor.id", getUsuarioLogueado().getId()).fetch();
		
		notFoundIfNull(object);
		
		try {
			render(type, object, templates);
		} catch (TemplateNotFoundException e) {
			render(getControllerName() + "/asignarPacientes.html", type, object, templates);
		}
		
	}
	
	public static void confirmarAsignarcionPaciente(Long templatePlanId, Long pacienteId) throws Exception {
		
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		
		// Hacer este metodo... que recibe un template y un paciente y se le asigna un plan de ese template.
		// va a la newPLan2 o se lo asigna de una? Gus.
		
		TemplatePlan templatePlan = TemplatePlan.findById(templatePlanId);
		
		Paciente paciente = Paciente.findById(pacienteId);
		
		notFoundIfNull(templatePlan);
		
        Plan nuevoPlan = new Plan(paciente, templatePlan);
		
        nuevoPlan.save();
        Notificador.emailAsignacionPlanAPaciente(paciente, (Nutri)getUsuarioLogueado(), templatePlan);
		
        redirect("/nutri");
	}
	
	public static boolean hasNutri() {
		return session.get("nutri_nombre") != null;
	}
	
	public static void desasignarNutricionista(){
		Notificador.emailDesasignarNutricionista(session.get("nutri_nombre"), session.get("nutri_mail"), session.get("paciente_nombre"), session.get("paciente_mail"));
		Paciente paciente = (Paciente)getUsuarioLogueado();
		Nutri nutri = paciente.getNutricionista();
		nutri.desasignarPaciente(paciente);
		paciente.setNutricionista(null);
		paciente.setEstadoPaciente(null);
		nutri.save();
		paciente.save();
		session.remove("nutri_nombre");
		session.remove("nutri_mail");
		Pacientes.index();
	}
	
	@Restrict("NUTRI")
	public static void crearObjetivoManual(String pacienteId) throws Exception{
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Paciente object = (Paciente)type.findById(pacienteId);
		session.put("paciente_mail", object.getEmail());
		session.put("paciente_nombre", object.getNombre());
		ManualObjectives.newManualObjective(Long.parseLong(pacienteId));
	}
	
	public static void comentarioNutri() {
		String comentario = params.get("comentario");
		String pacienteId = params.get("pacienteId");
		
		Paciente paciente = Paciente.findById(Long.valueOf(pacienteId));
		Nutri nutri = (Nutri) getUsuarioLogueado();
		
		Notificador.emailComentarioNutri(nutri, paciente, comentario);
		
		list(0, null, null, null, null);
	}
	
	@Restrict("NUTRI")
	public static List<List<Long>> cargarGraficoPacientesAdquiridos(Date fechaInicio, Date fechaFin, Long objetivoId) throws Exception {

		List<List<Long>> datosGrafico = new ArrayList<List<Long>>();

		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);

		Nutri nutri = (Nutri) getUsuarioLogueado();
		
		notFoundIfNull(nutri);
		
		Long datoIndex = 0L;
		
		// arma una cadena asi [1,1890],[2,2004],[3,2590],[4,1989]
		for (PacienteAdquirido pacienteHistorico : nutri.getPacientesAdquiridos()) {
			
			List<Long> registro = new ArrayList<Long>();
			
			if(pacienteHistorico.getFechaAlta().after(fechaInicio) && pacienteHistorico.getFechaAlta().before(fechaFin)) {
				registro.add(datoIndex++);
				registro.add(new Long("1"));
				datosGrafico.add(registro);
			}
		}
		
		return datosGrafico; 
		
	}

}
